package de.tuhh.simsearch.model.persistence.contentmgmt.entities;

import java.io.Serializable;
import java.math.BigInteger;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;

import de.tuhh.simsearch.model.persistence.contentmgmt.files.FileAccess;

/**
 * The file entity represents a file in the database as a database table. The file has an id which is the primary key
 * for the file entity table. The file also has a displayed file name, a content id, which contains the information
 * about the content type (see {@link Constants}), an owner, a file path, a file name which is generated by the filename the
 * file had when it was uploaded plus a time stamp, also a description and a set of categories {@link CategoryEntity}.
 * 
 * The actual file is stored by {@link FileAccess}.
 * 
 * @author SimSearch 1
 * @see CategoryEntity
 */
@Entity
public class FileEntity implements Serializable {

  private static final long serialVersionUID = 1L;

  @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private BigInteger id;

  private String displayedFilename;

  private Integer contentID;

  private String owner;

  private String path;

  private String filename;

  private String description;

  @ManyToMany private Set<CategoryEntity> categories = new HashSet<CategoryEntity>();

  /**
   * The class contructor which sets a file name and the path to the file
   * 
   * @param filename
   *          the file name
   * @param path
   *          the path to the file
   */
  public FileEntity(String filename, String path) {

    this.setFileName(filename);
    this.setPath(path);

  }

  protected FileEntity() {

  }

  /**
   * Gets the id of this file entity
   * 
   * @return the id
   */
  public BigInteger getId() {

    return id;
  }

  /**
   * Sets the id for this file entity
   * 
   * @param id
   *          the id
   */
  public void setId(BigInteger id) {

    this.id = id;
  }

  /**
   * Sets the file name
   * 
   * @param filename
   *          the filename to set
   */
  public void setFileName(String filename) {

    this.filename = filename;
  }

  /**
   * Gets the file name
   * 
   * @return the filename
   */
  public String getFileName() {

    return filename;
  }

  /**
   * Gets the path
   * 
   * @return the path
   */
  public String getPath() {

    return path;
  }

  /**
   * Sets the path to the file
   * 
   * @param path
   *          the path to set
   */
  public void setPath(String path) {

    this.path = path;
  }

  /**
   * Gets the owner of this file
   * 
   * @return the name of the owner
   */
  public String getOwner() {

    return owner;
  }

  /**
   * Sets the owner for this file entity
   * 
   * @param owner
   *          the name of the owner
   */
  public void setOwner(String owner) {

    this.owner = owner;
  }

  /**
   * Gets the displayed file name
   * 
   * @return the displayed file name
   */
  public String getDisplayedFilename() {

    return displayedFilename;
  }

  /**
   * Sets the displayed file name
   * 
   * @param displayedFilename
   *          the displayed file name
   */
  public void setDisplayedFilename(String displayedFilename) {

    this.displayedFilename = displayedFilename;
  }

  /**
   * Gets the content id of this file entity
   * 
   * @return the content type
   */
  public Integer getContentID() {

    return contentID;
  }

  /**
   * Sets the content id for this file entity
   * 
   * @param contentID
   *          the content type to set
   */
  public void setContentID(Integer contentID) {

    this.contentID = contentID;
  }

  /**
   * Gets the set of category entities. The resulting set is unmodifiable!
   * 
   * @return the set of category entities
   */
  public Set<CategoryEntity> getCategories() {

    return Collections.unmodifiableSet(categories);

  }

  /**
   * Adds a category to this file entity
   * 
   * @param c
   *          the category to add
   */
  public void addCategory(CategoryEntity c) {

    this.categories.add(c);
    if (!(c.getFiles().contains(this))) {

      c.addFile(this);
    }

  }

  protected void setCategories(Set<CategoryEntity> categories) {

    this.categories = categories;
  }

  /**
   * Removes a category from this file entity
   * 
   * @param c
   *          the category to remove
   */
  public void removeCategory(CategoryEntity c) {

    this.categories.remove(c);
    if (c.getFiles().contains(this)) {

      c.removeFile(this);
    }
  }

  /**
   * Gets the description for this file entity
   * 
   * @return the description
   */
  public String getDescription() {

    return description;
  }

  /**
   * Sets the description for this file entity
   * 
   * @param description
   *          the description
   */
  public void setDescription(String description) {

    this.description = description;
  }

}
